extends Node2D
class_name BottomBlocksArea

var existBlocksData:Array
var existBlockNodes:Array
var maxBlockCountPerLine = 10
var blockSize = 16

func _ready():
	existBlocksData = []
	

func testOverlap(blocksData):
	var overlap = false
	for blockData in blocksData:
		if overlap:
			break
		for existBlockData in existBlocksData:
			var existBlockCellPosX = existBlockData["cellPos"][0]
			var existBlockCellPosY = existBlockData["cellPos"][1]
			var blockCellPosX = blockData["cellPos"][0]
			var blockCellPosY = blockData["cellPos"][1]
			if blockCellPosX == existBlockCellPosX and blockCellPosY == existBlockCellPosY:
				overlap = true
				break
	return overlap


func addBlocks(blocksData):
	for blockData in blocksData:
		existBlocksData.append(blockData)
		
	var destroyLineCount = tryDestroyBlocks()
	updateView()
	
	var lose = testLose()
	
	if lose:
		GlobalSignals.GAME_END.emit()
	else:
		GlobalSignals.GAME_CONTINUE.emit()
		
	if destroyLineCount > 0:
		GlobalSignals.MAIN_VIEW_CHANGED.emit()
		GlobalSignals.SCORE_GETTED.emit(destroyLineCount)
		GlobalSignals.PLAY_SOUND.emit(SoundManager.DESTROY_LINE)
	
	
func testLose():
	var result = false
	for blockData in existBlocksData:
		if blockData["cellPos"][1] < 0:
			result = true
			break
	return result
	
	
func tryDestroyBlocks():
	var destroyLineCount = 0
	
	var blocksDataDict = categoryBlocksData()
	var line2Destroy = findDestroyableLine(blocksDataDict)
	while line2Destroy != -1:
		destroyLineCount += 1
		destroyLine(line2Destroy, blocksDataDict)
		line2Destroy = findDestroyableLine(blocksDataDict)
	
	return destroyLineCount
		

func destroyLine(line, blocksDataDict:Dictionary): 
	var blocksDataArr = blocksDataDict[line]
	for blockData in blocksDataArr:
		existBlocksData.remove_at(existBlocksData.find(blockData))
	blocksDataDict.erase(line)	
	
	for cellY in range(line - 1, -1, -1):
		if not blocksDataDict.has(cellY): continue
		
		var newLine = cellY + 1
		if not blocksDataDict.has(newLine):
			blocksDataDict[newLine] = []
			
		blocksDataArr = blocksDataDict[cellY] as Array
		for blockData in blocksDataArr:
			blockData["positionTrans"][1] += blockSize
			blockData["cellPos"][1] += 1
			blocksDataDict[newLine].append(blockData)
		
		blocksDataDict.erase(cellY)


func findDestroyableLine(blocksDataDict:Dictionary):
	var result = -1
	for cellY in blocksDataDict.keys():
		var blocksDataArr:Array = blocksDataDict[cellY] as Array
		if blocksDataArr.size() >= maxBlockCountPerLine:
			result = cellY
			break
	return result


func categoryBlocksData():
	var result = {}
	for blockData in existBlocksData:
		var blockCellY = blockData["cellPos"][1]
		if not result.has(blockCellY):
			result[blockCellY] = []
		result[blockCellY].append(blockData)
	return result
	

func getBlocksData():
	return existBlocksData
	

func updateViewByBlocksData(blocksData):
	existBlocksData = blocksData
	updateView()


func updateView():
	for existBlockData in existBlocksData:
		var exist = false
		var foundBlockNode:Block
		for existBlockNode in existBlockNodes:
			var existBlockDataPosTransX = existBlockData["positionTrans"][0]
			var existBlockDataPosTransY = existBlockData["positionTrans"][1]
			var existBlockNodePosX = existBlockNode.position.x
			var existBlockNodePosY = existBlockNode.position.y
			if existBlockDataPosTransX == existBlockNodePosX and existBlockDataPosTransY == existBlockNodePosY:
				exist = true
				foundBlockNode = existBlockNode
				break
		
		if exist:
			foundBlockNode.init(foundBlockNode.position, existBlockData["color"])
		else:
			var newBlockNode:Block = Global.createSceneInst("Block") as Block
			var targetPos = Vector2i(existBlockData["positionTrans"][0], existBlockData["positionTrans"][1])
			add_child(newBlockNode)
			newBlockNode.init(targetPos, existBlockData["color"])
			existBlockNodes.append(newBlockNode)
	
	var existBlockNodesCount = existBlockNodes.size()
	for existBlockNodeIndex in range(existBlockNodesCount-1, -1, -1):
		var existBlockNode = existBlockNodes[existBlockNodeIndex]
		
		var ifExistData = false
		for existBlockData in existBlocksData:
			var existBlockDataPosTransX = existBlockData["positionTrans"][0]
			var existBlockDataPosTransY = existBlockData["positionTrans"][1]
			var existBlockNodePosX = existBlockNode.position.x
			var existBlockNodePosY = existBlockNode.position.y
			if existBlockDataPosTransX == existBlockNodePosX and existBlockDataPosTransY == existBlockNodePosY:
				ifExistData = true
				break
		
		if not ifExistData:
			existBlockNodes.remove_at(existBlockNodeIndex)
			var node = existBlockNode as Node2D
			node.queue_free()
			
		
	
